import os
import json
import pygame as pg
from . import tool
from . import constants as c
from . import map, entity

class Level(tool.State):
    def __init__(self):
        tool.State.__init__(self)
    
    def startup(self, current_time, game_info):
        # 保存状态的开始时间
        self.start_time = current_time
        # 保存游戏信息
        self.game_info = game_info
        self.loadMap()
        # 如果在地图配置文件中设置了格子信息，则读取出来
        grid = self.map_data[c.MAP_GRID] if c.MAP_GRID in self.map_data else None
        # 创建地图类
        self.map = map.Map(c.GRID_X_LEN, c.GRID_Y_LEN, grid)
        # 创建生物组
        self.setupGroup()
        # 设置初始状态为空闲状态
        self.state = c.IDLE
        # 记录回合数
        if c.G_LOGINSTATE:
            self.round = c.G_CLIENT.round
        else:
            self.round = 1
        # 显示next_turn的时间
        self.start_time = 0

    def loadMap(self):
        '''加载地图配置文件'''
        if c.G_LOGINSTATE:
            f = c.G_CLIENT.map
        else:
            map_file = 'level_' + str(self.game_info[c.LEVEL_NUM]) + '.json'
            file_path = os.path.join('data', 'map', map_file)
            f = json.load(open(file_path))
        # json.load 函数将json文件内容解析后返回一个字典
        self.map_data = f

    def setupGroup(self):
        # 创建生物组 1
        self.group1 = entity.EntityGroup(1)
        # 根据关卡地图配置文件中的生物组 1 的配置，创建生物组 1 的生物
        self.group1.createEntity(self.map_data[c.GROUP1], self.map)
        # 创建生物组 2
        self.group2 = entity.EntityGroup(2)
        # 根据关卡地图配置文件中的生物组 2 配置，创建生物组 2 的生物
        self.group2.createEntity(self.map_data[c.GROUP2], self.map)
        # 创建伤害显示的管理组列表
        self.hurt_group = []

    def update(self, surface, current_time, mouse_pos, key_down):
        '''游戏的更新函数'''
        self.current_time = current_time

        if self.state == c.IDLE:

            self.map.updateMapShowIDLE(pg.mouse.get_pos())

            # 获取下一个行动的生物——点击选中
            if mouse_pos is not None:
                result = self.getClickEntity(mouse_pos)
                x, y = mouse_pos

                if result is not None:
                    entity = result
                    # 保存当前行动生物
                    self.map.active_entity = entity
                    # 设置运行类状态为生物行为选择状态
                    self.state = c.SELECT

                elif (x >= 600 and x <= 800 and y >= 300 and y <= 500):
                    if c.G_LOGINSTATE:
                        map = self.getmap()
                        c.G_CLIENT.upload(c.G_ACTIVEGAME['game_id'], map)
                        self.done = True
                        self.next = c.ONLINE_UPLOAD
                    else:
                        if self.map.active_group == 1:
                            self.group1.nextTurn()
                            self.map.active_group = 2
                            self.round += 1
                        elif self.map.active_group == 2:
                            self.group2.nextTurn()
                            self.map.active_group = 1

                    self.start_time = self.current_time


        elif self.state == c.SELECT:
            self.map.updateMapShow(pg.mouse.get_pos())
            if mouse_pos is not None:
                self.mouseClick(mouse_pos)
        elif self.state == c.ENTITY_ACT:
            # 更新地图的背景显示
            self.map.updateMapShow(pg.mouse.get_pos())
            # 更新两个生物组中生物的状态
            self.group1.update(current_time, self)
            self.group2.update(current_time, self)
            if self.map.active_entity.state == c.IDLE:
                # 当前行动生物状态变成空闲状态，表示生物行动结束
                self.state = c.IDLE
        
        remove_list = []
        for hurt in self.hurt_group:
            # 更新伤害显示对象的图形坐标
            hurt.update()
            if hurt.shouldRemove():
                # 如果有伤害显示对象需要删除，添加到删除列表中
                remove_list.append(hurt)
        for hurt in remove_list:
            # 遍历删除列表，从伤害显示管理组中删除
            self.hurt_group.remove(hurt)

        # 检查游戏状态
        self.checkGameState()
        # 绘制地图
        self.draw(surface)

    def getClickEntity(self, mouse_pos):
        x, y = mouse_pos
        # 获取鼠标位置所在的地图位置
        map_x, map_y = self.map.getMapIndex(x, y)
        if self.map.isValid(map_x, map_y) is False:
            return None
        entity = self.map.entity_map[map_y][map_x]
        if entity is not None:
            if entity.group_id == self.map.active_group:
               return entity
            else:
                return None
        else:
            return None

    def mouseClick(self, mouse_pos):
        # 判断鼠标点击的位置，当前行动生物是否可以走到
        if self.map.checkMouseClick(mouse_pos):
            # 鼠标点击的位置，当前行动生物可以走到，重设地图背景格子类型
            self.map.resetBackGround()
            # 设置运行类状态为生物行为执行状态
            self.state = c.ENTITY_ACT
    
    def addHurtShow(self, hurt):
        self.hurt_group.append(hurt)

    def getmap(self):
        mapdict = {}
        mapdict['mapgrid'] = self.map_data['mapgrid']
        mapdict['group1'] = []
        mapdict['group2'] = []
        for items in self.map.entity_map:
            for item in items:
                if item is not None:
                    if item.group_id == 1:
                        entitydict = {}
                        entitydict['name'] = item.entity_name
                        entitydict['x'] = item.map_x
                        entitydict['y'] = item.map_y
                        entitydict['health'] = item.health
                        mapdict['group1'].append(entitydict)
                    elif item.group_id == 2:
                        entitydict = {}
                        entitydict['name'] = item.entity_name
                        entitydict['x'] = item.map_x
                        entitydict['y'] = item.map_y
                        entitydict['health'] = item.health
                        mapdict['group2'].append(entitydict)

        return mapdict

    def checkGameState(self):
        # 如果有一个生物组没有生物了，关卡结束
        if self.group1.isEmpty() or self.group2.isEmpty():
            # 设置关卡运行状态结束
            self.done = True
            if c.G_LOGINSTATE:
                if self.group1.isEmpty():
                    c.G_CLIENT.win(c.G_ACTIVEGAME['game_id'])
                    # 如果胜利，下一个状态是关卡胜利状态
                    self.next = c.LEVEL_WIN
            else:
                # 约定敌方是生物组 1，我方是生物组 2
                if self.group1.isEmpty():
                    # 如果胜利，下一个状态是关卡胜利状态
                    self.next = c.LEVEL_WIN
                else:
                    # 如果失败，下一个状态是关卡失败状态
                    self.next = c.LEVEL_LOSE

    def draw(self, surface):
        # 绘制游戏地图显示
        self.map.drawBackground(surface)
        # 绘制两个生物组中生物的图形
        self.group1.draw(surface)
        self.group2.draw(surface)
        
        for hurt in self.hurt_group:
            # 绘制伤害显示图形
            hurt.draw(surface)

        # 显示按钮
        turn_image = pg.image.load(os.path.join("resources", "graphics", "button.png"))
        surface.blit(turn_image, [580, 350])

        # 显示next turn提示
        font1 = pg.font.SysFont(None, 50)
        if (self.current_time - self.start_time) < 1000:
            round_text = 'Next Turn!'
        else:
            round_text = '                        '
        round_image = font1.render(round_text, True, c.BLACK, c.LIGHTYELLOW)
        surface.blit(round_image, [580, 200])

        # 显示回合信息
        level_text = 'Round ' + str(self.round)
        level_image = font1.render(level_text, True, c.SKY_BLUE, c.LIGHTYELLOW)
        surface.blit(level_image, [580, 100])

        if c.G_LOGINSTATE:
            level_text = 'Game id: ' + str(c.G_ACTIVEGAME['game_id'])
            level_image = font1.render(level_text, True, c.SKY_BLUE, c.LIGHTYELLOW)
            surface.blit(level_image, [480, 200])

            level_text = 'Opponent: ' + str(c.G_ACTIVEGAME['opponent_name'])
            level_image = font1.render(level_text, True, c.SKY_BLUE, c.LIGHTYELLOW)
            surface.blit(level_image, [480, 300])

